層是模型非常重要的角色,也是模型訓練時張量運算的執行者。層也需要經過build的動作,產生對應的初始權重,供訓練時使用。而訓練時也會透過各層的 Call 函式來執行相關計算與張量之內積。
回顧一下前文使用 keras.layers.core.dense 時,如 Sequence文章 訓練過程:
如果模型未經過build的動作,在初次執行模型訓練時,會檢查出來並先執行模型的build,並逐一對層做build的動作。
在大致了解使用 keras 內建層於初始與訓練的運作後,嘗試來看自定義層也會如何運作。
範例如下:
import tensorflow as tf
from tensorflow.keras import layers
from tensorflow.keras.models import Model
class SimpleDense(layers.Layer):
def __init__(self, units=32):
super(SimpleDense, self).__init__()
self.units = units
def build(self, input_shape):
self.w = self.add_weight(shape=(input_shape[-1], self.units),
initializer='random_normal',
trainable=True)
self.b = self.add_weight(shape=(self.units,),
initializer='random_normal',
trainable=True)
def call(self, inputs):
return tf.matmul(inputs, self.w) + self.b
from keras.models import Sequential
model = Sequential([
SimpleDense(512),
layers.Dense(10, activation="softmax")
])
model.compile(optimizer="rmsprop",
loss="sparse_categorical_crossentropy",
metrics=["accuracy"])
from keras.datasets import mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype("float32") / 255
test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype("float32") / 255
model.fit(train_images, train_labels, epochs=1, batch_size=128)
在運作過程大致上和只使用內建 Dense Layer 類似,差異在藍色區塊。
當要對每一個層做build的動作時,如果是自定義Layer ( SimpleDense),在keras.engine.sequential._build_graph_network_for_inferred_shape函式中會判斷此自定義Layer是否Functional construction mode,因為判斷為True所以會進入keras.engine.base_layer.Layer._functional_construction_call,經過keras.engine.base_layer.Layer._keras_tensor_symbolic_call會到keras.engine.base_layer.Layer._infer_output_signature,其中直接執行keras.engine.base_layer.Layer._maybe_build -> SimpleDense.build,自定義的build函式即使用keras.engine.base_layer.Layer.add_weight 來初始化SimpleDense.w 與 SimpleDense.b。
而下方流程中,真正執行每層的運算時,透過迭代,到了自定義的SimpleDense,會呼叫本身的call 函式,然後執行tf.matmul(inputs, SimpleDense.w) + SimpleDense.b
,最後輸出結果送至下一個迭代的層之Input。
以上是將自定義Layer於 Sequence Model 運作的過程記錄於此。